Repository navigation
Conversation
The ZIP is portable only as a folder: Offloader.exe needs _internal beside it
and refuses to start without the installation lock file. This adds
Offloader-{version}-portable.exe, the desktop app as one self-extracting file
that runs from any folder.
It skips the installation lock. No installer or maintenance helper manages the
folder it sits in, so requiring a lock file would stop it starting and
creating one would litter the user's folder. The installed programs still take
the lock; the portable path goes through its own entry point rather than a
runtime guess about how the executable was frozen.
The builder treats it like the other release outputs: it signs and verifies
the outer executable, checks its embedded version, records its digest in the
build record so --skip-build cannot reuse a swapped file, and lists it in
SHA256SUMS.txt. The smoke runner starts a copy from an empty folder with a
minimal PATH and fails if it writes anything beside itself.
It has no CLI and no in-place update. The ZIP and installer still provide
those. The native modules it unpacks at launch keep the signatures they were
frozen with; only the outer executable is signed by this pipeline.
owenpkent
left a comment
There was a problem hiding this comment.
Reviewed d458fcb for the portable entry point, PyInstaller one-file target, build record, signing order, output validation, and smoke runner.
No actionable defect found in the new portable-specific paths. The regular GUI retains its default installation lock, the portable entry opts out explicitly, the external executable's digest is included in the build record, and both reuse and verify-only paths check that artifact. Signing precedes the final record and output checksums. The smoke runner copies the executable into its own directory and checks for neighboring files after launch.
Validation: 23 focused artifact/entry/pipeline tests passed. The source-identity test was deselected because this review used an exported commit snapshot without Git metadata. Current-head CI reports success. A native Windows freeze, hardware-token signature, and interactive portable launch were not repeated on this Linux host.
owenpkent
left a comment
There was a problem hiding this comment.
No additional actionable defect found in this incremental diff.
Reviewed the PyInstaller single-file target, portable entry behavior, installed-versus-portable lock handling, signing order, portable checksum record, verify-only checks and copied-executable smoke path. The separate portable target is reflected consistently in the build and artifact checks.
Validation: 22 focused portable artifact/entry/pipeline tests passed in a separate pinned source export; one symlink-dependent case skipped and one Git-source-identity test was deselected because the export lacks .git metadata. Current-head CI reports successful matrix/build/frozen checks; the diff check passes.
Limits: no fresh onefile freeze, physical clean-machine launch, hardware signing, antivirus exercise or actual installation. These are source-level checks plus recorded CI evidence, not a new portable-release qualification.
Pinned scope: declared base bf69fd36cd7923b6b09476963cb6d7250aa0fe7a, merge base bf69fd36cd7923b6b09476963cb6d7250aa0fe7a, head 12a4da481669ceac00243f91f62362f594bae012. Existing discussion and current-head checks were reviewed; no threads were resolved and no formal approval or merge is being issued.
# Conflicts: # README.md
# Conflicts: # README.md
Stacked on #13; merge that first, or retarget this to
mainafter it lands.What
Adds
Offloader-{version}-portable.exe: the desktop app as one file that runs from any folder without installing. The existing ZIP stays; it is still the only portable way to get the CLI.build/windows/portable_entry.py: new entry point that runs the GUI without the installation lock.gui_entry.pygains alockflag; installed programs still require the lock.offloader.spec: onefile target outside the bundle, with its own version resource.build.py: checks the embedded version, signs and verifies the outer exe, records its digest in the build record (so--skip-buildcannot reuse a swapped file), smoke-tests it, and lists it inSHA256SUMS.txt.--verify-onlyverifies its signature.smoke.py --portable: starts a copy from an empty folder with a minimal PATH and fails if it writes anything beside itself.Why no lock
No installer or maintenance helper manages the folder a portable exe sits in. Requiring the lock file would stop it starting; creating one would litter the user's folder. The installer never touches the portable exe, so there is nothing for the lock to protect.
Limits
Testing
python -m pytest -q: 797 passed, 12 skipped.python -m ruff check src tests scripts build/windows: clean.build.py --clean --no-sign --no-installerin a Python 3.12 venv withrequirements-build.txt: built, all smoke checks passed including the portable launch. Output 58,333,663 bytes.